#include "Monster.h"
#include <Windows.h>
#include <mmsystem.h>
#include "Hunter.h"

CMonster::CMonster(CHunter *theHunter){
	this->theHunter = theHunter;

	position = originalPos = Vector3(0.0, 0.0, 0.0);

	hp = 0;
	lastAtkTime = 0;
	distFromHunter = 0;

	active = false;

	state = MonsterState::IDLE;
}
CMonster::~CMonster(){
	if (theHunter != NULL)
		theHunter = NULL;
}

void CMonster::Init(){
	active = true;

	hp = 100;
	position = originalPos = Vector3(Math::RandFloatMinMax(15.0, 85.0), Math::RandFloatMinMax(15.0, 85.0), 0.0);

	state = MonsterState::IDLE;
}

int CMonster::getHP(){
	return hp;
}
int CMonster::getDistFromHunter(){
	return distFromHunter;
}
Vector3 CMonster::getPosition(){
	return position;
}
MonsterState CMonster::getState(){
	return state;
}
bool CMonster::isActive(){
	return active;
}

void CMonster::setHP(int hp){
	this->hp = hp;
}
void CMonster::setActive(bool active){
	this->active = active;
}

void CMonster::setCurrentState(MonsterState State)
{
	this->state = State;
}

void CMonster::Update(){
	distFromHunter = (theHunter->getPos() - position).Length();

	updateState();
}
void CMonster::render(){
	glPushMatrix();
	glColor3f(1, 0, 0);
	glTranslatef(this->position.x, this->position.y, 0);
	glScalef(5, 5, 1);
	glutSolidCube(1);
	glPopMatrix();
}

void CMonster::updateState(){
	if (hp <= 0){
		state = MonsterState::DIE;
		return;
	}

	switch (state){
	case MonsterState::IDLE:
		if (theHunter != NULL && theHunter->getHp() > 0)
			if ((theHunter->getCurrentState() == State::STATE_ATTACK && theHunter->getTarget() == this) ||
				distFromHunter <= 15)
				state = MonsterState::ATTACK;

		break;

	case MonsterState::ATTACK:
		if (distFromHunter > 50 || theHunter->getCurrentState() == State::STATE_DIE)
			state = MonsterState::RETURN;
		else if (theHunter->getCurrentState() == State::STATE_FLEE)
			state = MonsterState::CHASE;

		if ((timeGetTime() - lastAtkTime) > 1000 && distFromHunter <= 10){
			theHunter->setHp(theHunter->getHp() - (rand() % 25 + 1));
			lastAtkTime = timeGetTime();
		}

		break;

	case MonsterState::CHASE:
		if (distFromHunter > 50 || theHunter == NULL)
			state = MonsterState::RETURN;
		else if ((theHunter->getCurrentState() == State::STATE_ATTACK && theHunter->getTarget() == this) ||
			distFromHunter <= 5)
			state = MonsterState::ATTACK;

		position += (theHunter->getPos() - position) * 0.01;

		break;

	case MonsterState::RETURN:
	{
		Vector3 distFromOriginalPos = originalPos - position;

		if (theHunter != NULL){
			if ((theHunter->getCurrentState() == State::STATE_ATTACK && theHunter->getTarget() == this) || distFromHunter < 5)
				state = MonsterState::ATTACK;
			if (distFromOriginalPos.Length() <= 10)
				state = MonsterState::IDLE;
		}

		position += (originalPos - position) * 0.05;
	}
	break;

	case MonsterState::DIE:
		active = false;
		position = originalPos = Vector3(0.0, 0.0, 0.0);
		hp = 0;
		break;
	}
}